//初始数据库结构
const dbData = [
  {
    dbName: "masterDB", //数据库名称
    version: 1, //数据库版本号,当结构发生变化时
    tables: [
      //表
      {
        name: "SYS_favorites", //表名称
        keyPath: "uid", //主键
        autoIncrement: false, //主键是否自增
        index: [
          //索引
          {
            name: "name_index", //索引名称
            key: "name", //索引key
          },
        ],
      },
      {
        name: "SYS_keyword",
        keyPath: "id",
      },
    ],
  },
  {
    dbName: "guestDB",
    version: 1,
    tables: [
      {
        name: "MY_demo",
        keyPath: "id",
      },
    ],
  },
];

// 使用示例
// import DB from '@/utils/db'

// 初始化创建数据库 一般在项目启动时就执行了
// await DB.create()

// 打开某个数据库，返回数据库实例
// const database = await DB.open("dbName")

// 在打开的数据库中添加数据到tablenName表
// await database.add("tablenName", data)

// 查询
// await database.get("tablenName", key)

// 查询 根据索引
// await database.indexGet("tablenName", "indexName", indexVal)

// 修改
// await database.put("tablenName", data)

// 删除
// await database.delete("tablenName", key)

// 获取所有
// await database.getAll("tablenName")

// 清空某个表数据
// await database.clear("tablenName")

// 获取某个表信息
// database.getTable("tablenName")

// 获取所有表
// database.getTables()

// 关闭数据库连接
// database.close()

export default {
  //建立数据库，表，初始数据
  create() {
    var promiseArray = [];
    const addDB = (db) => {
      return new Promise((resolve, reject) => {
        const request = indexedDB.open(db.dbName, db.version);
        (request.onupgradeneeded = (e) => {
          const thisDB = e.target.result;
          db.tables.forEach((item) => {
            let table = null;
            if (thisDB.objectStoreNames.contains(item.name)) {
              //已存在表，删除旧index
              table = e.target.transaction.objectStore(item.name);
              table.indexNames.length > 0 &&
                table.indexNames.forEach((indexName) => {
                  table.deleteIndex(indexName);
                });
            } else {
              //创建新的表
              table = thisDB.createObjectStore(item.name, {
                keyPath: item.keyPath,
                autoIncrement: item.autoIncrement,
              });
            }
            //建立index
            item.index &&
              item.index.forEach((ind) => {
                table.createIndex(ind.name, ind.key, { unique: false });
              });
          });
        }),
          (request.onsuccess = (e) => {
            return resolve(e.target.result);
          });
        request.onerror = (e) => {
          return reject(e);
        };
      });
    };
    dbData.forEach((db) => {
      promiseArray.push(addDB(db));
    });
    return new Promise((resolve, reject) => {
      Promise.all(promiseArray)
        .then((e) => {
          resolve(e);
        })
        .catch((e) => {
          reject(e);
        });
    });
  },
  //所有数据库
  databases() {
    return indexedDB.databases();
  },
  //打开数据库
  open(dbName) {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(dbName);
      request.onsuccess = (e) => {
        const database = new this.database(e.target.result);
        resolve(database);
      };
      request.onerror = (e) => {
        reject(e);
      };
    });
  },
  //删除数据库
  deleteDB(dbName) {
    return indexedDB.deleteDatabase(dbName);
  },
  //数据库类
  database: function (IDBDatabase) {
    this.IDBDatabase = IDBDatabase;

    /**
     * 添加行数据
     * @param {string} tableName 表名
     * @param {object} data 数据
     * @returns {promise}
     */
    this.add = (tableName, data) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName).add(data);
        request.onsuccess = (e) => {
          resolve(e);
        };
        request.onerror = (e) => {
          reject(e);
        };
      });
    };

    /**
     * 修改行数据，未查询到就新增
     * @param {string} tableName 表名
     * @param {object} data 数据
     * @returns {promise}
     */
    this.put = (tableName, data) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName).put(data);
        request.onsuccess = (e) => {
          resolve(e);
        };
        request.onerror = (e) => {
          reject(e);
        };
      });
    };

    /**
     * 删除行
     * @param {string} tableName 表名
     * @param {string} key 主键
     * @returns {promise}
     */
    this.delete = (tableName, key) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName).delete(key);
        request.onsuccess = (e) => {
          resolve(e);
        };
        request.onerror = (e) => {
          reject(e);
        };
      });
    };

    /**
     * 根据主键获取行
     * @param {string} tableName 表名
     * @param {string} key 主键
     * @returns {promise}
     */
    this.get = (tableName, key) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName).get(key);
        request.onsuccess = () => {
          resolve(request.result || null);
        };
        request.onerror = (e) => {
          reject(e);
        };
      });
    };

    /**
     * 根据索引获取行
     * @param {string} tableName 表名
     * @param {string} indexName 索引库名称
     * @param {string} indexVal 索引值
     * @returns {promise}
     */
    this.indexGet = (tableName, indexName, indexVal) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite")
          .objectStore(tableName)
          .index(indexName)
          .get(indexVal);
        request.onsuccess = () => {
          resolve(request.result || null);
        };
        request.onerror = (e) => {
          reject(e);
        };
      });
    };

    /**
     * 获取所有行
     * @param {string} tableName 表名
     * @returns {promise}
     */
    this.getAll = (tableName) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName).getAll();
        request.onsuccess = () => {
          resolve(request.result || null);
        };
        request.onerror = (e) => {
          reject(e);
        };
      });
    };

    /**
     * 清空表
     * @param {string} tableName 表名
     * @returns {promise}
     */
    this.clear = (tableName) => {
      return new Promise((resolve, reject) => {
        const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName).clear();
        request.onsuccess = (e) => {
          resolve(e);
        };
        request.onerror = (err) => {
          reject(err);
        };
      });
    };

    /**
     * 获取表信息
     * @returns {IDBObjectStore}
     */
    this.getTable = (tableName) => {
      const request = IDBDatabase.transaction([tableName], "readwrite").objectStore(tableName);
      return request;
    };

    /**
     * 获取所有的表
     * @returns {[IDBObjectStore]}
     */
    this.getTables = () => {
      const tables = [];
      for (let item of IDBDatabase.objectStoreNames) {
        tables.push(IDBDatabase.transaction([item], "readwrite").objectStore(item));
      }
      return tables;
    };

    /**
     * 关闭数据库连接
     * @returns {}
     */
    this.close = () => {
      return IDBDatabase.close();
    };
  },
};
